import { defineComponent, PropType, computed } from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
import RecursiveNodeContent from '../recursive-node-content/recursive-node-content';
import { IRecursiveTreeNode, NodeDropType } from '../recursive-tree-util';
import './recursive-tree-node.scss';

// 递归组件
export const RecursiveTreeNode = defineComponent({
  name: 'RecursiveTreeNode',
  props: {
    node: {
      type: Object as PropType<IRecursiveTreeNode>,
      required: true,
    },
    expandedKeys: {
      type: Array as PropType<Array<string | number>>,
      required: true,
    },
    overItem: {
      type: Object as PropType<IRecursiveTreeNode>,
    },
    separator: {
      type: Boolean,
      default: true,
    },
    allowDrop: {
      type: Function as PropType<
        (
          _draggingNode: IRecursiveTreeNode,
          _dropNode: IRecursiveTreeNode,
          _type: 'inner' | 'prev' | 'next',
        ) => boolean
      >,
    },
    allowDrag: {
      type: Function as PropType<
        (_draggingNode: IRecursiveTreeNode) => boolean
      >,
    },
  },
  emits: {
    nodeDrop: (
      _draggingNode: IRecursiveTreeNode,
      _dropNode: IRecursiveTreeNode,
      _dropType: NodeDropType,
    ) => true,
    dragStart: (_draggingNode: IRecursiveTreeNode) => true,
    dragEnd: (_draggingNode: IRecursiveTreeNode) => true,
  },
  setup(props, { emit }) {
    const ns = useNamespace(`org-recursive-tree-node`);
    // 采用展开节点key的方式计算处理，父加载成功后传递展开节点key
    const activeItem = computed(() => {
      if (props.node.children && props.node.children.length > 0) {
        return props.node.children.find(_node =>
          props.expandedKeys.includes(_node.id),
        );
      }
      return undefined;
    });

    const handleNodeDrop = (
      _draggingNode: IRecursiveTreeNode,
      _dropNode: IRecursiveTreeNode,
      _dropType: NodeDropType,
    ): void => {
      emit('nodeDrop', _draggingNode, _dropNode, _dropType);
    };

    return {
      ns,
      activeItem,
      handleNodeDrop,
    };
  },
  render() {
    const activeContent =
      this.activeItem &&
      this.node.children &&
      this.node.children.length > 1 &&
      this.$slots.active?.(this.activeItem);

    return (
      <div class={this.ns.b()}>
        <div class={this.ns.e('header')}>
          {this.separator && (
            <div class={this.ns.e('separator-container')}>
              <div class={this.ns.e('separator')}>
                <div
                  class={[
                    this.ns.em('separator', 'line-part'),
                    this.ns.is('line-left', true),
                  ]}
                ></div>
                <div
                  class={[
                    this.ns.em('separator', 'line-part'),
                    this.ns.is('line-right', true),
                  ]}
                ></div>
              </div>
            </div>
          )}
          <RecursiveNodeContent
            node={this.node}
            activeItem={this.activeItem}
            allow-drop={this.allowDrop}
            allow-drag={this.allowDrag}
            onNodeDrop={this.handleNodeDrop}
          >
            {{
              default: (_params: { data: IData }) => {
                return this.$slots.default?.(_params);
              },
            }}
          </RecursiveNodeContent>
          {activeContent && (
            <div class={this.ns.e('active-content')}>{activeContent}</div>
          )}
        </div>
        {this.activeItem && (
          <div class={this.ns.e('children')}>
            <RecursiveTreeNode
              node={this.activeItem}
              expandedKeys={this.expandedKeys}
              allow-drop={this.allowDrop}
              allow-drag={this.allowDrag}
              onNodeDrop={this.handleNodeDrop}
            >
              {{
                default: (params: { data: IData }) =>
                  this.$slots.default?.(params),
                active: (params: { data: IData }) =>
                  this.$slots.active?.(params),
              }}
            </RecursiveTreeNode>
          </div>
        )}
      </div>
    );
  },
});

export default RecursiveTreeNode;
